package priv.dajie.tzzq.spider.dota.c5;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import priv.dajie.tzzq.Base;
import priv.dajie.tzzq.bot.exception.NetworkException;
import priv.dajie.tzzq.common.ApplicationContextUnit;
import priv.dajie.tzzq.model.QualityName;
import priv.dajie.tzzq.service.PlatformService;
import priv.dajie.tzzq.spider.Base.DotaSpider;
import priv.dajie.tzzq.spider.model.SpiderInfo;
import priv.dajie.tzzq.spider.model.*;
import priv.dajie.tzzq.common.Tools;

import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class C5DotaSpider extends Base implements Runnable, DotaSpider {

    private SpiderInfo spiderInfo;
    private PlatformService c5Service;
    private SpiderMode mode; // 0 插入普通表，否则 插入pro表
    private Logger logger = LogManager.getLogger(this.getClass().getName());

    public C5DotaSpider(SpiderInfo spiderInfo, SpiderMode mode) {
        this.spiderInfo = spiderInfo;
        this.c5Service = (PlatformService) ApplicationContextUnit.getInstance().getBean("c5Service");
        this.mode = mode;
    }

    public C5DotaSpider(SpiderMode mode){
        this(null, mode);
    }

    @Override
    public void setSpiderInfo(SpiderInfo spiderInfo) {
        this.spiderInfo = spiderInfo;
    }

    @Override
    public void startSpider() {
        String hero = null;
        String type = null;
//        c5Table.setDate(new Date());
        while (true) {
            InfoElement infoElement = spiderInfo.getInfoElement();
            if(infoElement!=null){
                if(infoElement.getElementType() == ElementType.HERO){
                    hero = infoElement.getName();
                    type = null;
                }
                else {
                    type = infoElement.getName();
                    hero = null;
                }
            }
            else {
                break;
            }
//            System.out.println("剩余："+ spiderInfo.getSize()+ " | c5"+ infoElement);
            logger.info("剩余："+ spiderInfo.getSize()+ " | c5"+ infoElement);
            for (String rarity : spiderInfo.getRarity().keySet()) {
                List<SellingInfo> ls = getItem(rarity, hero, type);
                for (SellingInfo info : ls) {
                    updateDB(info);
                }
            }
        }
    }

    public void updateDB(SellingInfo info) {

        if(mode == SpiderMode.NEWTABLE) {
            c5Service.addItemPro(info);
        }
        else{
            c5Service.addItem(info);
        }

        ItemInfo dbItemInfo = c5Service.getInfoById(info.getInfo().getId());
        if (dbItemInfo == null) {
            String steamName = getSteamName(info.getInfo().getId());
            info.getInfo().setSteamName(steamName);
            c5Service.addInfo(info.getInfo());
        } else if (!dbItemInfo.equals(info.getInfo()) || (dbItemInfo.getSteamName()==null)) { //数据库与爬虫数据不一致 或 数据库steamName为空 则 更新数据
            String steamName = getSteamName(info.getInfo().getId());
            info.getInfo().setSteamName(steamName);
            c5Service.updateInfo(info.getInfo());
        }
    }

    @Override
    public List<SellingInfo> getItem(String rarity, String hero, String type) {
        int page = 1;
        int only = 0;
        int error = 0;
        List<SellingInfo> list = new ArrayList<>();
        while (true) {
//            System.out.println(String.format("第%d页,only=%d", page,only));
            try {
                URIBuilder uriBuilder = new URIBuilder("https://open.c5game.com/v1/store");
                uriBuilder.setParameter("rarity", rarity);
                uriBuilder.setParameter("hero", hero);
                uriBuilder.setParameter("type", type);
                uriBuilder.setParameter("page", String.valueOf(page));
                uriBuilder.setParameter("appid", "570");
                uriBuilder.setParameter("only", String.valueOf(only)); // only = 0代表销售，= 1代表求购
                HttpGet httpGet = new HttpGet(uriBuilder.build());
                logger.debug(httpGet);
//                System.out.println(httpGet);
//                System.out.println(httpGet);
                String jsonText;
                try {
                    jsonText = open(httpGet);
                }catch (NetworkException e){
                    logger.error(e);
                    try {
                        Thread.sleep(1000 * ++error);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                    if(error>10) {
                        throw e;
                    }
                    continue;
                }
                JSONObject json = JSON.parseObject(jsonText);
                if (json.getInteger("status") == 550) {
                    if (only == 0) {
                        page = 1;
                        only++;
                        continue;
                    } else {
                        break;
                    }
                }
                JSONArray dataList = json.getJSONObject("data").getJSONArray("list"); // 获取返回的数据列表
                for (int i = 0; i < dataList.size(); i++) {
                    JSONObject data = dataList.getJSONObject(i);
                    String id = data.getString("item_id");
                    String name = data.getString("name");
                    QualityName qualityName = Tools.getQualityName(name);
//                    String quality = data.getString("quality_name");
                    String rarityName = data.getString("rarity_name");
                    String heroName = type == null ? spiderInfo.getHeroCN(hero) : spiderInfo.getTypeCN(type);
                    double price = data.getDouble("price");
                    int num = data.getInteger("num");
                    TradeType tradeType = data.getString("product_type").equals("S") ? TradeType.SELL : TradeType.BUY;
                    ItemInfo itemInfo = new ItemInfo(id, qualityName, rarityName, heroName, null, Platform.C5);
                    SellingInfo sellingInfo = new SellingInfo(itemInfo, price, num, tradeType);
                    list.add(sellingInfo);
                }
                page++;
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    public String getSteamName(String id) {
        HttpGet httpGet = new HttpGet("https://www.c5game.com/dota/" + id + "-S.html");
        String html = open(httpGet);
        Document document = Jsoup.parse(html);
        // 查找包含steanName的url
        Element div = document.select("div .ft-gray.steamUrl").first();
        if (div == null) // 页面搜索不带信息则返回null
            return null;
        Element aurl = div.select("a").first();
        String href = aurl.attr("href");
        // 对url进行匹配
        Pattern pattern = Pattern.compile("570/(.*)");
        Matcher matcher = pattern.matcher(href);
        if (matcher.find())
            return matcher.group(1).trim(); // 获取匹配的内容 并去除两端空格
        return null;
    }

    @Override
    public void run() {
        startSpider();
    }
}
